package com.remoting.core.support.hystrix;

import java.util.function.Function;
import java.util.function.Supplier;


import com.netflix.hystrix.HystrixCommand.Setter;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;

/**
 * Hystrix工具类
 * <p>说明:</p>
 * <li></li>
 * @author DuanYong
 * @since 2017年11月13日下午2:26:23
 */
public class HystrixUtil {
	/**
	 * 执行函数调用
	 * <p>说明:</p>
	 * <li></li>
	 * @author DuanYong
	 * @param method 方法名称
	 * @param timeout 超时时间
	 * @param function 正常业务处理函数
	 * @param fallbackFunction 服务降级处理函数
	 * @param p 参数
	 * @return 执行结果
	 * @since 2017年11月13日下午4:04:07
	 */
	public static <P> Object execute(String method,int timeout,Function<P,Object> function,Function<P,Object> fallbackFunction,P p){
		Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(""));//被调用服务
        setter.andCommandKey(HystrixCommandKey.Factory.asKey(method));//被调用服务的一个被调用方法
        setter.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(timeout));
        InvokeTimeoutParamHystrixCommand<P> command = new InvokeTimeoutParamHystrixCommand<P>(setter, function,fallbackFunction,p,method,timeout);
        //同步执行
        return command.execute();
	}
	/**
	 * 执行函数调用
	 * <p>说明:</p>
	 * <li></li>
	 * @author DuanYong
	 * @param method 方法名称
	 * @param timeout 超时时间
	 * @param function 正常业务处理函数
	 * @param fallbackFunction 服务降级处理函数
	 * @return 执行结果
	 * @since 2017年11月13日下午4:04:53
	 */
	public static Object execute(String method,int timeout,Supplier<Object> function,Supplier<Object> fallbackFunction){
		Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(""));//被调用服务
        setter.andCommandKey(HystrixCommandKey.Factory.asKey(method));//被调用服务的一个被调用方法
        setter.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(timeout));
        InvokeTimeoutNonParamHystrixCommand command = new InvokeTimeoutNonParamHystrixCommand(setter, function,fallbackFunction,method,timeout);
        //同步执行
        return command.execute();
	}
}
